/*
    This file is part of Emu.

    Emu is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Emu is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Emu.  If not, see <http://www.gnu.org/licenses/>. */
#include <QColorDialog>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QMessageBox>

#include "etriggereditor.h"

/* These #defines for use with the two comboboxes so the numbers don't seem to
   be so magical. The first set is for _patternCombo, the second for
   _actionCombo. */

#define PAT_REGEXP    0
#define PAT_WILDCARD  1
#define PAT_PLAINTEXT 2

#define ACT_NONE      0
#define ACT_OMIT      1
#define ACT_HIGHLIGHT 2

ETriggerEditor::ETriggerEditor(QWidget *parent, bool addmode)
    : QDialog(parent)
{
    QFormLayout *layout = new QFormLayout;
    QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok |
                                                 QDialogButtonBox::Cancel);
    _nameLine = new QLineEdit;
    _patternLine = new QLineEdit;
    _patternCombo = new QComboBox;
    _replyEdit = new QTextEdit;
    _caseCheck = new QCheckBox(tr("Check Case"));
    _continueCheck = new QCheckBox(tr("Continue Matching"));
    _actionCombo = new QComboBox;
    _highlightColor = Qt::black;
    _highlightButton = new EPrefButton(_highlightColor, 0);

    _caseCheck->setToolTip(
    tr("If case should be checked when matching the trigger."));
    _continueCheck->setToolTip(
    tr("If this trigger matches, continue matching triggers."));
    _replyEdit->setToolTip(
    tr("(Optional) A message to send to the server."));

    _patternCombo->addItem(tr("Regular Expression"));
    _patternCombo->addItem(tr("Wildcard"));
    _patternCombo->addItem(tr("Plain text"));

    _actionCombo->addItem(tr("None"));
    _actionCombo->addItem(tr("Omit Text"));
    _actionCombo->addItem(tr("Highlight Text"));

    _highlightButton->setEnabled(false);

    layout->addRow(tr("Name:"), _nameLine);
    layout->addRow(tr("Pattern:"), _patternLine);
    layout->addRow(tr("Pattern Type:"), _patternCombo);
    layout->addRow(tr("Reply To Server:"), _replyEdit);
    layout->addWidget(_caseCheck);
    layout->addWidget(_continueCheck);
    layout->addRow(tr("Text Action:"), _actionCombo);
    layout->addRow(tr("Highlight Color:"), _highlightButton);
    layout->addWidget(box);

    setLayout(layout);

    if (addmode)
        setWindowTitle(tr("Add Trigger"));
    else
        setWindowTitle(tr("Edit Trigger"));

    connect(_actionCombo, SIGNAL(currentIndexChanged(int)), this,
            SLOT(actionChanged(int)));
    connect(_highlightButton, SIGNAL(clicked()), this,
            SLOT(highlightClicked()));
    connect(box, SIGNAL(rejected()), this, SLOT(reject()));
    connect(box, SIGNAL(accepted()), this, SLOT(validate()));
}

void ETriggerEditor::actionChanged(int index)
{
    _highlightButton->setEnabled(index == ACT_HIGHLIGHT);
}

void ETriggerEditor::highlightClicked()
{
    QColor newColor = QColorDialog::getColor(_highlightColor, this);

    if (newColor.isValid())
        _highlightColor = newColor;
}

void ETriggerEditor::useTrigger(ETrigger trigger)
{
    /* See session/etrigger.h for options. */
    int options = trigger.options();

    if (options & TRIG_KEEPGOING)
        _continueCheck->setChecked(true);

    if (trigger.caseSensitivity() == Qt::CaseSensitive)
        _caseCheck->setChecked(true);

    if (trigger.patternSyntax() == QRegExp::Wildcard)
        _patternCombo->setCurrentIndex(PAT_WILDCARD);
    else if (trigger.patternSyntax() == QRegExp::FixedString)
        _patternCombo->setCurrentIndex(PAT_PLAINTEXT);

    if (options & TRIG_HIGHLIGHT)
        _actionCombo->setCurrentIndex(ACT_HIGHLIGHT);
    else if (options & TRIG_OMIT)
        _actionCombo->setCurrentIndex(ACT_OMIT);

    _nameLine->setText(trigger.name());
    _patternLine->setText(trigger.pattern());
    _replyEdit->setPlainText(trigger.output());
    _highlightColor = trigger.highlightColor();
}

void ETriggerEditor::validate()
{
    int options = 0;
    QRegExp::PatternSyntax s = QRegExp::RegExp;
    Qt::CaseSensitivity cs = Qt::CaseInsensitive;

    if (_patternLine->text().isEmpty()) {
        QMessageBox::critical(this, tr("Error"),
                              tr("Triggers must have a pattern."));
        return;
    }

    if (_patternCombo->currentIndex() == PAT_WILDCARD)
        s = QRegExp::Wildcard;
    else if (_patternCombo->currentIndex() == PAT_PLAINTEXT)
        s = QRegExp::FixedString;

    _trigger.setPattern(_patternLine->text());
    _trigger.setPatternSyntax(s);

    if (!_trigger.isValid()) {
        QMessageBox::critical(this, tr("Error"),
                              tr("Error creating trigger : %1")
                              .arg(_trigger.errorString()));
        return;
    }

    _trigger.setName(_nameLine->text());

    if (_caseCheck->isChecked())
        cs = Qt::CaseSensitive;

    if (!_replyEdit->toPlainText().isEmpty())
        options |= TRIG_HASREPLY;

    if (s == QRegExp::RegExp &&
        _trigger.pattern().count(QRegExp("\\((?!\\?\\!)")))
        options |= TRIG_CAPTURING;

    if (_continueCheck->isChecked())
        options |= TRIG_KEEPGOING;

    if (_actionCombo->currentIndex() == ACT_HIGHLIGHT)
        options |= TRIG_HIGHLIGHT;
    else if (_actionCombo->currentIndex() == ACT_OMIT)
        options |= TRIG_OMIT;

    _trigger.setHighlightColor(_highlightColor);
    _trigger.setCaseSensitivity(cs);
    _trigger.setOutput(_replyEdit->toPlainText());
    _trigger.setOptions(options);

    accept();
}
